import type { DatePatterns, TimePieceValue, KeyOfTimePiece, TimePieceUnit } from '../declarations';
import { Numbers } from './Numbers';
import { Strings } from './Strings';

/**
 * - 作者: DoooReyn
 * - 日期: 2023.10.29
 * - 名称: Dates
 * - 描述: 日期、时间辅助工具
 */
export class Dates {
    /**
     * 转换为日期对象
     * @param date 日期表现形式
     * @returns
     */
    static fromDate(date?: DatePatterns) {
        return date !== undefined ? new Date(date) : new Date();
    }

    /**
     * 转换为本地日期字符串形式
     * @param date 日期表现形式
     * @returns
     */
    static toLocaleDate(date?: DatePatterns) {
        return this.fromDate(date).toLocaleDateString();
    }

    /**
     * 转换为本地时间字符串形式
     * @param date 日期表现形式
     * @returns
     */
    static toLocaleTime(date?: DatePatterns) {
        return this.fromDate(date).toLocaleTimeString();
    }

    /**
     * 将秒数转换为指定有效位数的字符串
     * @param time 秒数 (x1000)
     * @param bit 小数点后有效位数，默认2位
     * @returns 秒数字符串
     */
    static toSeconds(time: number, bit: number = 2) {
        return Numbers.toFractionAfter(time / 1000, bit);
    }

    /**
     * 将秒数转换为日期字符串
     * @param seconds 秒数 (x1000)
     * @returns
     */
    static toDateTime(seconds: number) {
        seconds = Numbers.floor(seconds);
        const dict: TimePieceValue = { ms: 0, s: 0, m: 0, h: 0, D: 0, M: 0, Y: 0 };
        const units: TimePieceValue = { ms: 1000, s: 60, m: 60, h: 24, D: 30, M: 12, Y: 10000 };
        let unit: KeyOfTimePiece;
        for (const u in units) {
            if (seconds <= 0) break;
            unit = u as KeyOfTimePiece;
            dict[unit] = seconds % units[unit];
            seconds = Numbers.floor(seconds / units[unit]);
        }
        return dict;
    }

    /**
     * 按照指定格式化方法将秒数转换为字符串
     * @param value 秒数
     * @param formatter 格式化方法
     * @returns
     */
    static toDateTimeByFormatter(value: number, formatter: (k: KeyOfTimePiece, v: number) => string) {
        const time = this.toDateTime(value);
        return (Object.keys(time) as KeyOfTimePiece[])
            .reverse()
            .map((v) => formatter(v, time[v]))
            .join('');
    }

    /**
     * 秒数转换为时间格式
     * @param value 秒数
     * @param fmt 格式
     * @returns
     * @example
     * ```typescript
     * toDateTimeInFormat(1671785953022, {
     *     ms: "毫秒",
     *     s: "秒",
     *     h: "时",
     *     m: "分",
     *     D: "天",
     *     M: "月",
     *     Y: "年"
     * });
     * // 53年08月29天08时59分13秒22毫秒
     * ```
     */
    static toDateTimeInFormat(value: number, fmt: TimePieceUnit) {
        return this.toDateTimeByFormatter(value, (k, v) => {
            return fmt[k] ? `${Strings.padStart(v.toString(), '0', 2)}${fmt[k]}` : '';
        });
    }
}
